﻿using Kimd.Common;
using Kimd.Logic;
using Kimd.Machine;
using Kimd.Motion;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WorkStation.Common;

namespace WorkStation.Logic
{
    /// <summary>
    /// 贴合轨道
    /// </summary>
    public class PasteConveyorLogic : FlowBase
    {
        private Axis _conveyor;
        private Axis _lift;
        private Cylinder _heatOn;
        private Cylinder _vac;
        private Cylinder _stationNeedPlateOut;
        private Cylinder _stationIsOutPlateNow;
        private Sensor _plateInPosition;
        private Sensor _heatAlarm1;
        private Sensor _heatAlarm2;
        private Sensor _vacSensed;
        private Sensor _backStationAllowPlateOut;
        private Sensor _backStationPlateOutFinish;

        public PasteConveyorLogic(string flowName, FlowManager flowmanager) 
            : base(flowName, flowmanager)
        {
            _conveyor = MachineResource.Instance.MachineAxis["贴合流线步进"];
            _lift = MachineResource.Instance.MachineAxis["贴合顶升步进"];
            _heatOn = MachineResource.Instance.MachineCylinder["流线加热开"];
            _vac = MachineResource.Instance.MachineCylinder["贴合流线真空"];
            _stationNeedPlateOut = MachineResource.Instance.MachineCylinder["本站出料请求"];
            _stationIsOutPlateNow = MachineResource.Instance.MachineCylinder["本站出料中"];
            _plateInPosition = MachineResource.Instance.MachineSensor["贴合到位光电"];
            _heatAlarm1 = MachineResource.Instance.MachineSensor["加热报警"];
            _heatAlarm2 = MachineResource.Instance.MachineSensor["加热报警2"];
            _vacSensed = MachineResource.Instance.MachineSensor["贴合流线真空感应"];
            _backStationAllowPlateOut = MachineResource.Instance.MachineSensor["下站入料允许"];
            _backStationPlateOutFinish = MachineResource.Instance.MachineSensor["下站入料完成"];

            RegisterDirectSignal("贴合轨道板到位");
            RegisterDirectSignal("要板");
        }

        public override void Calibrate()
        {
            base.Calibrate();
        }

        public override void Home()
        {
            if (_conveyor.ServoWarn)
                _conveyor.ClearAlarm();
            Thread.Sleep(200);
            if (!_conveyor.ServoOn)
                _conveyor.SetServoOn();
            Thread.Sleep(200);
            _conveyor.Stop(false);

            if (_lift.ServoWarn)
                _lift.ClearAlarm();
            Thread.Sleep(200);
            if (!_lift.ServoOn)
                _lift.SetServoOn();

            //复位信号
            _stationNeedPlateOut.Off();
            _stationIsOutPlateNow.Off();
            _vac.Off();
            //检查是否有料盘
            checkProductStatus();

            SingleAxisGoHome(_lift);
            if (!CheckFlowCondition()) return;

            _conveyor.Zero();
        }

        public override void Init(out string errInfo)
        {
            base.Init(out errInfo);
        }

        public override void InSingleRunMode()
        {
            base.InSingleRunMode();
        }

        public override void Method()
        {
            if (!CheckFlowCondition()) return;

            //等待来自缓存流线的有料信号
            WaitForSignal("缓存流线", "缓存板到位");
            if (!CheckFlowCondition()) return;
            //向缓存流线要板
            SetSignal("要板");
            SingleAxisMoveContinuous(_conveyor, true);
            WaitSensor(_plateInPosition, 10000, "贴合流线等待板到位超时!请检查是否卡料",
                       () => { _conveyor.Stop(false); },
                       () => { SingleAxisMoveContinuous(_conveyor, true); });
            //到板后延时
            Thread.Sleep(100);
            _conveyor.Stop(false);
            if (!CheckFlowCondition()) return;
            //顶板
            _vac.On();
            if (!GlobalVariable.IsDryRun)
            {
                WaitSensor(_vacSensed, 5000, "贴合工位轨道真空异常");
                if (!CheckFlowCondition()) return;
            }
            //顶起来
            SingleAxisMove2Point(_lift, "顶板位");
            if (!CheckFlowCondition()) return;
            SetSignal("贴合轨道板到位");

            WaitForSignal("贴合逻辑", "贴Block结束");
            if (!CheckFlowCondition()) return;

            //落盘
            SingleAxisMove2Point(_lift, "落盘位");
            if (!CheckFlowCondition()) return;
            //关真空
            _vac.Off();

            //请求出版
            _stationNeedPlateOut.On();
            if (!CheckFlowCondition()) return;

            if (!GlobalVariable.IsDryRun)
            {
                //等待后站允许出料
                while (!_backStationAllowPlateOut.WaitOn() && !IsBreak())
                {
                    Thread.Sleep(20);
                }
            }
            //置位轨道正在出料中标志
            _stationIsOutPlateNow.On();
            retry:
            //往后出料
            SingleAxisMoveContinuous(_conveyor, true);

            DateTime startTime = DateTime.Now;
            TimeSpan ts = DateTime.Now - startTime;
            while (_plateInPosition.WaitOn() && !IsBreak() && ts.TotalMilliseconds < 5000)
            {
                ts = DateTime.Now - startTime;
                Thread.Sleep(20);
            }
            if (ts.TotalMilliseconds >= 5000)
            {
                _conveyor.Stop(false);
                ShowWarnAndPause("贴合流线等待板子流出超时!", _conveyor.Module);
                if (!CheckFlowCondition()) return;
                goto retry;
            }
            Thread.Sleep(1000);
            //轨道停转
            _conveyor.Stop(false);
            _stationIsOutPlateNow.Off();
            _stationNeedPlateOut.Off();
            Thread.Sleep(1000);
            //结束
        }

        public override void OnStop()
        {
            base.OnStop();
        }

        public override bool PreStartCheck()
        {
            return base.PreStartCheck();
        }

        public override void SpotCheck()
        {
            base.SpotCheck();
        }
        public void checkProductStatus()
        {
            //while (_hasPlate.WaitOn() && !IsBreak())
            //{
            //    MachineMessageScheduler.Instance.Add(new MachineMessage(MessageType.InfoAndPause, $"贴合流道上有料盘，请取走", this.Description, 0, "系统"));
            //    //出错，停下所有线程
            //    _flowManager.Pause();
            //    //若为报错，需重新检测启动信号
            //    WaitForStart();
            //    if (!CheckFlowCondition()) return;

            //    Thread.Sleep(20);
            //}
        }
    }
}
